using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes.DomainAttributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Enums;
using System.Collections.Generic;
using System.ComponentModel;

namespace Baci.ArcGIS._RasterAnalysisTools._UseProximity
{
    /// <summary>
    /// <para>Calculate Distance</para>
    /// <para>Calculates the Euclidean distance from a single source or set of sources.</para>
    /// <para>计算与单个源或一组源的欧几里得距离。</para>
    /// </summary>    
    [DisplayName("Calculate Distance")]
    public class CalculateDistance : AbstractGPProcess
    {
        /// <summary>
        /// 无参构造
        /// </summary>
        public CalculateDistance()
        {

        }

        /// <summary>
        /// 有参构造
        /// </summary>
        /// <param name="_inputSourceRasterOrFeatures">
        /// <para>Input Source Raster or Features</para>
        /// <para><xdoc>
        ///   <para>The layer that defines the sources to calculate the distance to. The layer can be image service or feature service.</para>
        ///   <para>For image service, the input type can be integer or floating point.</para>
        ///   <para>For feature service, the input can be point, line or polygon.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>定义要计算到的距离的源的图层。图层可以是影像服务或要素服务。</para>
        ///   <para>对于影像服务，输入类型可以是整数或浮点。</para>
        ///   <para>对于要素服务，输入可以是点、线或面。</para>
        /// </xdoc></para>
        /// </param>
        /// <param name="_outputDistanceName">
        /// <para>Output Distance Name</para>
        /// <para>The name of the output distance raster service.</para>
        /// <para>输出距离栅格服务的名称。</para>
        /// </param>
        public CalculateDistance(object _inputSourceRasterOrFeatures, object _outputDistanceName)
        {
            this._inputSourceRasterOrFeatures = _inputSourceRasterOrFeatures;
            this._outputDistanceName = _outputDistanceName;
        }
        public override string ToolboxName => "Raster Analysis Tools";

        public override string ToolName => "Calculate Distance";

        public override string CallName => "ra.CalculateDistance";

        public override List<string> AcceptEnvironments => ["cellSize", "extent", "mask", "outputCoordinateSystem", "snapRaster"];

        public override object[] ParameterInfo => [_inputSourceRasterOrFeatures, _outputDistanceName, _maximumDistance, _outputCellSize, _outputDirectionName, _outputAllocationName, _allocationField, _outputDistanceRaster, _outputDirectionRaster, _outputAllocationRaster, _distanceMethod.GetGPValue(), _inputBarrierRasterOrFeatures, _outputBackDirectionName, _outputBackDirectionRaster];

        /// <summary>
        /// <para>Input Source Raster or Features</para>
        /// <para><xdoc>
        ///   <para>The layer that defines the sources to calculate the distance to. The layer can be image service or feature service.</para>
        ///   <para>For image service, the input type can be integer or floating point.</para>
        ///   <para>For feature service, the input can be point, line or polygon.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>定义要计算到的距离的源的图层。图层可以是影像服务或要素服务。</para>
        ///   <para>对于影像服务，输入类型可以是整数或浮点。</para>
        ///   <para>对于要素服务，输入可以是点、线或面。</para>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Input Source Raster or Features")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _inputSourceRasterOrFeatures { get; set; }


        /// <summary>
        /// <para>Output Distance Name</para>
        /// <para>The name of the output distance raster service.</para>
        /// <para>输出距离栅格服务的名称。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Distance Name")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _outputDistanceName { get; set; }


        /// <summary>
        /// <para>Maximum Distance</para>
        /// <para><xdoc>
        ///   <para>The maximum distance to calculate out to.</para>
        ///   <para>The units can be Kilometers, Meters, Miles, Yards, or Feet.</para>
        ///   <para>The default units are Meters.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>要计算的最大距离。</para>
        ///   <para>单位可以是公里、米、英里、码或英尺。</para>
        ///   <para>默认单位为米。</para>
        /// </xdoc></para>
        /// <para>单位： Meters | Kilometers | Feet | Yards | Miles </para>
        /// </summary>
        [DisplayName("Maximum Distance")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public string? _maximumDistance { get; set; } = null;


        /// <summary>
        /// <para>Output Cell Size</para>
        /// <para><xdoc>
        ///   <para>Set the cell size and units for the output raster.</para>
        ///   <para>The units can be Kilometers, Meters, Miles, Yards, or Feet.</para>
        ///   <para>The default units are Meters.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>设置输出栅格的像元大小和单位。</para>
        ///   <para>单位可以是公里、米、英里、码或英尺。</para>
        ///   <para>默认单位为米。</para>
        /// </xdoc></para>
        /// <para>单位： Meters | Kilometers | Feet | Yards | Miles </para>
        /// </summary>
        [DisplayName("Output Cell Size")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public string? _outputCellSize { get; set; } = null;


        /// <summary>
        /// <para>Output Direction Name</para>
        /// <para>The name of the output direction raster service.</para>
        /// <para>输出方向栅格服务的名称。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Direction Name")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public object _outputDirectionName { get; set; } = null;


        /// <summary>
        /// <para>Output Allocation Name</para>
        /// <para>The name of the output allocation raster service.</para>
        /// <para>输出分配栅格服务的名称。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Allocation Name")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public object _outputAllocationName { get; set; } = null;


        /// <summary>
        /// <para>Allocation Field</para>
        /// <para>A field on the source input that holds the values that define each source. It must be of type integer.</para>
        /// <para>源输入上的一个字段，用于保存定义每个源的值。它必须是整数类型。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Allocation Field")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public object _allocationField { get; set; } = null;


        /// <summary>
        /// <para>Output Distance Raster</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Distance Raster")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public object _outputDistanceRaster { get; set; }


        /// <summary>
        /// <para>Output Direction Raster</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Direction Raster")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public object _outputDirectionRaster { get; set; }


        /// <summary>
        /// <para>Output Allocation Raster</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Allocation Raster")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public object _outputAllocationRaster { get; set; }


        /// <summary>
        /// <para>Distance Method</para>
        /// <para><xdoc>
        ///   <para>Specifies whether to calculate the distance using a planar (flat earth) or a geodesic (ellipsoid) method.</para>
        ///   <bulletList>
        ///     <bullet_item>Planar—The distance calculation will be performed on a projected flat plane using a 2D Cartesian coordinate system. This is the default.</bullet_item><para/>
        ///     <bullet_item>Geodesic—The distance calculation will be performed on the ellipsoid. Therefore, regardless of input or output projection, the results do not change.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定是使用平面（平坦地球）还是测地线（椭球体）方法计算距离。</para>
        ///   <bulletList>
        ///     <bullet_item>平面—将使用 2D 笛卡尔坐标系在投影平面上执行距离计算。这是默认设置。</bullet_item><para/>
        ///     <bullet_item>测地线—将在椭球体上执行距离计算。因此，无论输入或输出投影如何，结果都不会改变。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Distance Method")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _distanceMethod_value _distanceMethod { get; set; } = _distanceMethod_value._Planar;

        public enum _distanceMethod_value
        {
            /// <summary>
            /// <para>Planar</para>
            /// <para>Planar—The distance calculation will be performed on a projected flat plane using a 2D Cartesian coordinate system. This is the default.</para>
            /// <para>平面—将使用 2D 笛卡尔坐标系在投影平面上执行距离计算。这是默认设置。</para>
            /// </summary>
            [Description("Planar")]
            [GPEnumValue("Planar")]
            _Planar,

            /// <summary>
            /// <para>Geodesic</para>
            /// <para>Geodesic—The distance calculation will be performed on the ellipsoid. Therefore, regardless of input or output projection, the results do not change.</para>
            /// <para>测地线—将在椭球体上执行距离计算。因此，无论输入或输出投影如何，结果都不会改变。</para>
            /// </summary>
            [Description("Geodesic")]
            [GPEnumValue("Geodesic")]
            _Geodesic,

        }

        /// <summary>
        /// <para>Input Barrier Raster or Features</para>
        /// <para><xdoc>
        ///   <para>Dataset that defines the barriers.</para>
        ///   <para>The barriers can be defined by an integer or floating point raster, or a feature layer.</para>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>定义障碍的数据集。</para>
        ///   <para>障碍可以由整数或浮点栅格或要素图层来定义。</para>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Input Barrier Raster or Features")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public object _inputBarrierRasterOrFeatures { get; set; } = null;


        /// <summary>
        /// <para>Output Back Direction Name</para>
        /// <para>The name of the output back direction raster service.</para>
        /// <para>输出返回方向栅格服务的名称。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Back Direction Name")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public object _outputBackDirectionName { get; set; } = null;


        /// <summary>
        /// <para>Output Back Direction Raster</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Output Back Direction Raster")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public object _outputBackDirectionRaster { get; set; }


        public CalculateDistance SetEnv(object cellSize = null, object extent = null, object mask = null, object outputCoordinateSystem = null, object snapRaster = null)
        {
            base.SetEnv(cellSize: cellSize, extent: extent, mask: mask, outputCoordinateSystem: outputCoordinateSystem, snapRaster: snapRaster);
            return this;
        }

    }

}